This invention relates to the field of data processing. More particularly, this invention relates to data processing systems supporting both native instructions and interpreted non-native instructions and within which it is desired to make subroutine calls from native code to a non-native subroutine.
It is a well known computer programming technique to utilise subroutine calls within a program structure. Such subroutine calls allow frequently used code segments to be re-used from different points within a computer program. When a computer program reaches a point at which it is desired to start execution of a subroutine, a call instruction will be executed to redirect processing to the start of the subroutine. At the end of the subroutine, a return instruction will be executed that returns processing control to the address within the program code immediately following the point from which the subroutine call was made.
It is known to provide computer program operations utilising a mix of native instructions that may be directly executed by a processor core and non-native instructions that require interpretation into the form of native instructions prior to execution. Typically, native instructions are more rapid to execute but have a lower code density and are more difficult to program than non-native instructions.
FIG. 14 of the accompanying drawings illustrates a known technique whereby a non-native caller routine may make a subroutine call to a non-native subroutine. The call is made by an invoke_static instruction that passes processing control to the start of the corresponding subroutine. At the end of the subroutine, a return instruction is executed that returns processing to the non-native instruction immediately following the invoke_static instruction.
FIG. 15 of the accompanying drawings illustrates a native caller program used to call a native subroutine. In this example, the caller native program and the subroutine native program are written in ARM object code form (using the native instructions of an ARM processor as produced by ARM Limited of Cambridge, England). The caller program issues a native call instruction BL<address> that passes control to the start of the native subroutine program. The BL<address> also stores a return address in a register of the processor core (in this example the link register lr) that points to the address following the subroutine call instruction. At the end of the native subroutine, a return instruction in the form of a MOVS pc lr native instruction serves to move the stored return address from the link register lr into the program counter register pc thereby directing processing to resume at the native instruction following the original calling instruction.
FIG. 16 of the accompanying drawings illustrates a common non-native subroutine that may be called by either native calling code or non-native calling code. Since the non-native subroutine is executed in a non-native mode, when the subroutine has completed, it is required to determine whether a return is being made to a non-native calling program, in which case a mode change is not required, or alternative to a native calling program, in which case a mode change is required. In order to achieve this, the return instruction at the end of the non-native subroutine has to test to determine whether or not a return is being made to a native calling program or a non-native calling program before the return is actually made. This slows down processing. Given below is an example of some ARM object code instructions that may be interpreted from the non-native return instruction at the end of the subroutine of FIG. 16 in order to carry out the appropriate determination and return to the native calling program or the non-native calling program as necessary:                do_return                    LDR Rtmp, [Rframe, #previous_frame]            CMP Rtmp, #0            BEQ return_to_native                        return_to_java                    Code to perform return to non-native Java code                        return_to_native                    Code to perform return to native ARM or Thumb codeIn this example code the return instruction is a Java bytecode that has been interpreted by a Java software interpreter into ARM object code that serves to determine whether or not the previous frame value from which the call was made was #0. If the previous frame value was #0, then this indicates that the calling program was a native program and a return to a native program mode (i.e. ARM object code) is made. If the previous frame value is not #0, then the calling program was a non-native program and a return to a non-native mode (i.e. Java) is made.                        
It will be appreciated that the extra processing needed each time a return is made to determine whether or not the calling program was a native calling program or a non-native calling program is a performance disadvantage. This is particularly the case since in a large majority of cases non-native subroutines are called from non-native calling programs and native subroutines are called from native calling programs with comparatively little intercalling between native and non-native routines. Thus, the checking in an overwhelming majority of cases produces a result indicating the mode is uncharged but must nevertheless take place on each return instruction in order to cater for the relatively rare cases of an intercall between native and non-native code.
FIG. 17 of the accompanying drawings illustrates a known system whereby a non-native veneer subroutine is called from calling native code as an indirect technique for triggering execution of a main non-native subroutine. The use of such veneer subroutines is a known technique for efficient programming.
Examples of known systems for translation between instruction sets and other background information may be found in the following: U.S. Pat. Nos. 5,805,895; 3,955,180; 5,970,242; 5,619,665; 5,826,089; 5,925,123; 5,875,336; 5,937,193; 5,953,520; 6,021,469; 5,568,646; 5,758,115; and 5,367,685; IBM Technical Disclosure Bulletin, March 1988, pp 308–309, “System/370 Emulator Assist Processor For a Reduced Instruction Set Computer”; IBM Technical Disclosure Bulletin, July 1986, pp 548–549, “Full Function Series/1 Instruction Set Emulator”; IBM Technical Disclosure Bulletin, March 1994, pp 605–606, “Real-Time CISC Architecture HW Emulator On A RISC Processor”; IBM Technical Disclosure Bulletin, March 1998, p 272, “Performance Improvement Using An EMULATION Control Block”; IBM Technical Disclosure Bulletin, January 1995, pp 537–540, “Fast Instruction Decode For Code Emulation on Reduced Instruction Set Computer/Cycles Systems”; IBM Technical Disclosure Bulletin, February 1993, pp 231–234, “High Performance Dual Architecture Processor”; IBM Technical Disclosure Bulletin, August 1989, pp 40–43, “System/370 I/O Channel Program Channel Command Word Prefetch”; IBM Technical Disclosure Bulletin, June 1985, pp 305–306, “Fully Microcode-Controlled Emulation Architecture”; IBM Technical Disclosure Bulletin, March 1972, pp 3074–3076, “Op Code and Status Handling For Emulation”; IBM Technical Disclosure Bulletin, August 1982, pp 954–956, “On-Chip Microcoding of a Microprocessor With Most Frequently Used Instructions of Large System and Primitives Suitable for Coding Remaining Instructions”; IBM Technical Disclosure Bulletin, April 1983, pp 5576–5577, “Emulation Instruction”; the book ARM System Architecture by S Furber; the book Computer Architecture: A Quantitative Approach by Hennessy and Patterson; and the book The Java Virtual Machine Specification by Tim Lindholm and Frank Yellin 1st and 2nd editions.